@@ -18,6 +18,11 @@ module LiquidDroppable |
||
18 | 18 |
yield [name, __send__(name)] |
19 | 19 |
} |
20 | 20 |
end |
21 |
+ |
|
22 |
+ def as_json |
|
23 |
+ return {} unless defined?(self.class::METHODS) |
|
24 |
+ Hash[self.class::METHODS.map { |m| [m, send(m).as_json]}] |
|
25 |
+ end |
|
21 | 26 |
end |
22 | 27 |
|
23 | 28 |
included do |
@@ -33,12 +38,10 @@ module LiquidDroppable |
||
33 | 38 |
self.class::Drop.new(self) |
34 | 39 |
end |
35 | 40 |
|
36 |
- class MatchDataDrop < Liquid::Drop |
|
37 |
- def initialize(object) |
|
38 |
- @object = object |
|
39 |
- end |
|
41 |
+ class MatchDataDrop < Drop |
|
42 |
+ METHODS = %w[pre_match post_match names size] |
|
40 | 43 |
|
41 |
- %w[pre_match post_match names size].each { |attr| |
|
44 |
+ METHODS.each { |attr| |
|
42 | 45 |
define_method(attr) { |
43 | 46 |
@object.__send__(attr) |
44 | 47 |
} |
@@ -64,7 +67,9 @@ module LiquidDroppable |
||
64 | 67 |
require 'uri' |
65 | 68 |
|
66 | 69 |
class URIDrop < Drop |
67 |
- URI::Generic::COMPONENT.each { |attr| |
|
70 |
+ METHODS = URI::Generic::COMPONENT |
|
71 |
+ |
|
72 |
+ METHODS.each { |attr| |
|
68 | 73 |
define_method(attr) { |
69 | 74 |
@object.__send__(attr) |
70 | 75 |
} |
@@ -92,7 +92,9 @@ module LiquidInterpolatable |
||
92 | 92 |
|
93 | 93 |
def interpolate_string(string, self_object = nil) |
94 | 94 |
interpolate_with(self_object) do |
95 |
- Liquid::Template.parse(string).render!(interpolation_context) |
|
95 |
+ catch :as_object do |
|
96 |
+ Liquid::Template.parse(string).render!(interpolation_context) |
|
97 |
+ end |
|
96 | 98 |
end |
97 | 99 |
end |
98 | 100 |
|
@@ -225,6 +227,25 @@ module LiquidInterpolatable |
||
225 | 227 |
JSON.dump(input) |
226 | 228 |
end |
227 | 229 |
|
230 |
+ # Returns a Ruby object |
|
231 |
+ # |
|
232 |
+ # It can be used as a JSONPath replacement for Agents that only support Liquid: |
|
233 |
+ # |
|
234 |
+ # Event: {"something": {"nested": {"data": 1}}} |
|
235 |
+ # Liquid: {{something.nested | as_object}} |
|
236 |
+ # Returns: {"data": 1} |
|
237 |
+ # |
|
238 |
+ # Splitting up a string with Liquid filters and return the Array: |
|
239 |
+ # |
|
240 |
+ # Event: {"data": "A,B,C"}} |
|
241 |
+ # Liquid: {{data | split: ',' | as_object}} |
|
242 |
+ # Returns: ['A', 'B', 'C'] |
|
243 |
+ # |
|
244 |
+ # as_object ALWAYS has be the last filter in a Liquid expression! |
|
245 |
+ def as_object(object) |
|
246 |
+ throw :as_object, object.as_json |
|
247 |
+ end |
|
248 |
+ |
|
228 | 249 |
private |
229 | 250 |
|
230 | 251 |
def logger |
@@ -443,7 +443,7 @@ class AgentDrop |
||
443 | 443 |
@object.short_type |
444 | 444 |
end |
445 | 445 |
|
446 |
- [ |
|
446 |
+ METHODS = [ |
|
447 | 447 |
:name, |
448 | 448 |
:type, |
449 | 449 |
:options, |
@@ -456,7 +456,9 @@ class AgentDrop |
||
456 | 456 |
:disabled, |
457 | 457 |
:keep_events_for, |
458 | 458 |
:propagate_immediately, |
459 |
- ].each { |attr| |
|
459 |
+ ] |
|
460 |
+ |
|
461 |
+ METHODS.each { |attr| |
|
460 | 462 |
define_method(attr) { |
461 | 463 |
@object.__send__(attr) |
462 | 464 |
} unless method_defined?(attr) |
@@ -119,4 +119,8 @@ class EventDrop |
||
119 | 119 |
def _location_ |
120 | 120 |
@object.location |
121 | 121 |
end |
122 |
+ |
|
123 |
+ def as_json |
|
124 |
+ {location: _location_.as_json, agent: @object.agent.to_liquid.as_json, payload: @payload.as_json, created_at: created_at.as_json} |
|
125 |
+ end |
|
122 | 126 |
end |
@@ -264,4 +264,59 @@ describe LiquidInterpolatable::Filters do |
||
264 | 264 |
expect(agent.interpolated['cleaned']).to eq('FOObar ZOObar') |
265 | 265 |
end |
266 | 266 |
end |
267 |
+ |
|
268 |
+ context 'as_object' do |
|
269 |
+ let(:agent) { Agents::InterpolatableAgent.new(name: "test") } |
|
270 |
+ |
|
271 |
+ it 'returns an array that was splitted in liquid tags' do |
|
272 |
+ agent.interpolation_context['something'] = 'test,string,abc' |
|
273 |
+ agent.options['array'] = "{{something | split: ',' | as_object}}" |
|
274 |
+ expect(agent.interpolated['array']).to eq(['test', 'string', 'abc']) |
|
275 |
+ end |
|
276 |
+ |
|
277 |
+ it 'returns an object that was not modified in liquid' do |
|
278 |
+ agent.interpolation_context['something'] = {'nested' => {'abc' => 'test'}} |
|
279 |
+ agent.options['object'] = "{{something.nested | as_object}}" |
|
280 |
+ expect(agent.interpolated['object']).to eq({"abc" => 'test'}) |
|
281 |
+ end |
|
282 |
+ |
|
283 |
+ context 'as_json' do |
|
284 |
+ def ensure_safety(obj) |
|
285 |
+ JSON.parse(JSON.dump(obj)) |
|
286 |
+ end |
|
287 |
+ |
|
288 |
+ it 'it converts "complex" objects' do |
|
289 |
+ agent.interpolation_context['something'] = {'nested' => Service.new} |
|
290 |
+ agent.options['object'] = "{{something | as_object}}" |
|
291 |
+ expect(agent.interpolated['object']).to eq({'nested'=> ensure_safety(Service.new.as_json)}) |
|
292 |
+ end |
|
293 |
+ |
|
294 |
+ it 'works with AgentDrops' do |
|
295 |
+ agent.interpolation_context['something'] = agent |
|
296 |
+ agent.options['object'] = "{{something | as_object}}" |
|
297 |
+ expect(agent.interpolated['object']).to eq(ensure_safety(agent.to_liquid.as_json.stringify_keys)) |
|
298 |
+ end |
|
299 |
+ |
|
300 |
+ it 'works with EventDrops' do |
|
301 |
+ event = Event.new(payload: {some: 'payload'}, agent: agent, created_at: Time.now) |
|
302 |
+ agent.interpolation_context['something'] = event |
|
303 |
+ agent.options['object'] = "{{something | as_object}}" |
|
304 |
+ expect(agent.interpolated['object']).to eq(ensure_safety(event.to_liquid.as_json.stringify_keys)) |
|
305 |
+ end |
|
306 |
+ |
|
307 |
+ it 'works with MatchDataDrops' do |
|
308 |
+ match = "test string".match(/\A(?<word>\w+)\s(.+?)\z/) |
|
309 |
+ agent.interpolation_context['something'] = match |
|
310 |
+ agent.options['object'] = "{{something | as_object}}" |
|
311 |
+ expect(agent.interpolated['object']).to eq(ensure_safety(match.to_liquid.as_json.stringify_keys)) |
|
312 |
+ end |
|
313 |
+ |
|
314 |
+ it 'works with URIDrops' do |
|
315 |
+ uri = URI.parse("https://google.com?q=test") |
|
316 |
+ agent.interpolation_context['something'] = uri |
|
317 |
+ agent.options['object'] = "{{something | as_object}}" |
|
318 |
+ expect(agent.interpolated['object']).to eq(ensure_safety(uri.to_liquid.as_json.stringify_keys)) |
|
319 |
+ end |
|
320 |
+ end |
|
321 |
+ end |
|
267 | 322 |
end |